#ifndef _lib_io_stream_h_
#define _lib_io_stream_h_

#include "io/io_exception.h"

template<class T> struct Stream;

typedef Stream<uint8> Raw_Stream;

// Generic stream interface.
// Actual semantics are left for the implementor.
template<class T>
struct Stream
{
	typedef T Element_Type;

	// Read at most 'count' elements into buf. Return number of actual
	// bytes read. Advance pos() if applicable.
	virtual int64 read(T* buf, int count)
	{
		throw IO_Exception("Unsupported");
	}

	// Read one element.
	T read()
	{
		T result;
		int elements_read = read(&result, 1);
		if (elements_read == 0)
			throw IO_Exception("Couldn't read stream");

		return result;
	}

	// Write 'count' elements. Advance pos() if applicable.
	virtual void write(const T* buf, int64 count)
	{
		throw IO_Exception("Unsupported");
	}

	// Write one element
	void write(const T& t)
	{
		write(&t, 1);
	}

	// Seek to given length.
	// pre(0 <= pos && pos <= length());
	// post(pos() == pos);
	virtual void seek(int64 pos)
	{
		throw IO_Exception("Unsupported");
	}

	// Position
	// post(0 <= pos() && pos() <= length());
	virtual int64 pos()
	{
		throw IO_Exception("Unsupported");
	}

	// Total length
	// post(length() >= 0);
	virtual int64 length()
	{
		throw IO_Exception("Unsupported");
	}

	virtual ~Stream()
	{
	}
};

#endif
